﻿/*--------------------------------------------------------------------------------
 * Adaptive Intelligence - Foundation Framework
 * Version 2.10
 * 
 * CNR Response Base Class
 *      Provides an abstract base definition for implementing responses in
 * a command-and-response protocol.
 *------------------------------------------------------------------------------*/

/*--------------------------------------------------------------------------------
 * System Imports
 *------------------------------------------------------------------------------*/
using System;
using Adaptive.Foundation;

namespace Adaptive.Foundation.Network.Cnr
{
    /// <summary>
    /// Provides an abstract base definition for implementing responses in 
    /// a command-and-response protocol.
    /// </summary>
    /// <remarks>
    /// This base class is intended to be extended for the specific application within a 
    /// particular command-and-response protocol, such as FTP, E/SMTP, POP3, and others.
    /// 
    /// The specifics of each Response implementation, and the related derivatives of the 
    /// <see cref="CnrResponseBase"/> implementations are left to the implementors
    /// of each protocol.
    /// </remarks>
    public abstract class CnrResponseBase : CnrObjectBase 
    {
        /*--------------------------------------------------------------------------------
         * Public Event Definitions
         *------------------------------------------------------------------------------*/
        #region Public Event Definitions
        #endregion

        /*--------------------------------------------------------------------------------
         * Private Constants Declarations
         *------------------------------------------------------------------------------*/
        #region Private Constants Declarations
        #endregion

        /*--------------------------------------------------------------------------------
         * Private Member Declarations
         *------------------------------------------------------------------------------*/
        #region Private Member Declarations
        /// <summary>
        /// Internal parser instance.
        /// </summary>
        private CnrDataParserBase _parserInstance;
        /// <summary>
        /// Internal renderer instance.
        /// </summary>
        private CnrDataRendererBase _rendererInstance;
        /// <summary>
        /// Response type value container.
        /// </summary>
        private int _responseTypeValue;
        /// <summary>
        /// Response data.
        /// </summary>
        private string _responseData;
        /// <summary>
        /// Sucess flag.
        /// </summary>
        private bool _success;
        #endregion

        /*--------------------------------------------------------------------------------
         * Constructor / Dispose / Destructor Methods
         *------------------------------------------------------------------------------*/
        #region Constructor / Dispose / Destructor Methods
        /// <summary>
        /// Initializes a new instance of the class.
        /// </summary>
        /// <param name="responseData">
        /// The data that constitutes the response.
        /// </param>
        public CnrResponseBase(string responseData)
            : base()
        {
            _rendererInstance = CreateRendererInstance();
            _parserInstance = CreateParserInstance();

            _responseData = responseData;
            ParseContent(_responseData);

        }
        /// <summary>
        /// Initializes a new instance of the class.
        /// </summary>
        /// <param name="responseData">
        /// The data that constitutes the response.
        /// </param>
        /// <param name="responseCode">
        /// A numeric value that identifies the response.
        /// </param>
        public CnrResponseBase(string responseData, int responseCode)
            : base()
        {
            _rendererInstance = CreateRendererInstance();
            _parserInstance = CreateParserInstance();

            _responseData = responseData;
            _responseTypeValue = responseCode;

            ParseContent(_responseData);
        }
        /// <summary>
        /// Deallocates internally allocated objects.
        /// </summary>
        /// <param name="disposing">
        /// A value indicating whether the object is being disposed.
        /// </param>
        protected override void Dispose(bool disposing)
        {
            if ((!Disposed) && (disposing))
            {
            }

            _rendererInstance = null;
            _parserInstance = null;
            _responseData = null;
            base.Dispose(disposing);
        }
        #endregion

        /*--------------------------------------------------------------------------------
         * Public Properties
         *------------------------------------------------------------------------------*/
        #region Public Properties
        /// <summary>
        /// Gets or sets the text defining the response.
        /// </summary>
        /// <value>
        /// The string data that constitutes the response.
        /// </value>
        public string ResponseData
        {
            get { return _responseData; }
            set { _responseData = value; }
        }
        /// <summary>
        /// Gets or sets a numeric value used to identify the Response.
        /// </summary>
        /// <value>
        /// An integer value to associate with the Response instance.
        /// </value>
        public int ResponseCode
        {
            get { return _responseTypeValue; }
            set { _responseTypeValue = value; }
        }
        /// <summary>
        /// Gets or sets a value indicating whether the current instance represents
        /// a response that indicates a successful operation.
        /// </summary>
        /// <value>
        /// <b>true</b> if the related operation was successful; otherwise, <b>false</b>.
        /// </value>
        public bool Success
        {
            get { return _success; }
            set { _success = value; }
        }
        /// <summary>
        /// 
        /// </summary>
        protected CnrDataRendererBase Renderer
        {
            get { return _rendererInstance; }
        }
        /// <summary>
        /// 
        /// </summary>
        protected CnrDataParserBase Parser
        {
            get { return _parserInstance; }
        }
        #endregion

        /*--------------------------------------------------------------------------------
         * Protected Methods / Event Methods
         *------------------------------------------------------------------------------*/
        #region Protected Methods / Event Methods
        /// <summary>
        /// Creates the protocol-specific protocol instance that will be used for internal parsing.
        /// </summary>
        protected abstract CnrDataParserBase CreateParserInstance();
        /// <summary>
        /// Creates the protocol-specific protocol instance that will be used for internal rendering.
        /// </summary>
        protected abstract CnrDataRendererBase CreateRendererInstance();
        /// <summary>
        /// Renders the Response as a string.
        /// </summary>
        /// <returns>
        /// A string containing the Response and parameter values.
        /// </returns>
        protected abstract string RenderResponse();
        /// <summary>
        /// Renders the Response as a string.
        /// </summary>
        /// <returns>
        /// A string containing the Response and parameter values.
        /// </returns>
        /// <param name="renderer">
        /// A <see cref="CnrDataRendererBase"/> instance used to render the Response.
        /// </param>
        protected abstract string RenderResponse(CnrDataRendererBase renderer);
        /// <summary>
        /// Parses the original data content into the Response object.
        /// </summary>
        /// <param name="originalData">
        /// The original data to be parsed.
        /// </param>
        protected abstract void ParseContent(string originalData);
        /// <summary>
        /// Parses the original data content into the Response object.
        /// </summary>
        /// <param name="parser">
        /// A <see cref="CnrDataParserBase"/> instance used to parse the Response text.
        /// </param>
        /// <param name="originalData">
        /// The original data to be parsed.
        /// </param>
        protected abstract void ParseResponse(CnrDataParserBase parser, string originalData);
        #endregion

        /*--------------------------------------------------------------------------------
         * Public Methods / Functions
         *------------------------------------------------------------------------------*/
        #region Public Methods / Functions
        /// <summary>
        /// Clears the contents of the object instance without disposing of the instance.
        /// </summary>
        public override void Clear()
        {
            _responseTypeValue = 0;
            _responseData = string.Empty;
        }
        /// <summary>
        /// Renders the response as a string.
        /// </summary>
        /// <returns>
        /// A protocol-rendered string.
        /// </returns>
        public virtual string Render()
        {
            return RenderResponse();
        }
        /// <summary>
        /// Parses the suypplied text into the protocol-specific object graph.
        /// </summary>
        /// <param name="originalText">
        /// The original text to be parsed.
        /// </param>
        public virtual void Parse(string originalText)
        {
            ParseContent(originalText);
        }
        #endregion
    }
}